import 'package:app/util/StringUtils.dart';
import 'package:app/util/WebSocketInheritedWidget.dart';
import 'package:bruno/bruno.dart';
import 'package:dio/dio.dart';
import 'package:flutter/material.dart';
import './SecureStorage.dart';

class ApiService{

  BuildContext? context;

  static String host = "http://192.168.100.199:8081/";



  late Dio _dio;

  static Map<String, String> header = {
    'Content-Type': 'application/json;charset=UTF-8',
    'X-Requested-with': 'XMLHttpRequest'
  };

  static ApiService of(BuildContext? context){
    ApiService apiService = ApiService();
    BrnLoadingDialog.show(context!);
    apiService.context = context;
    apiService.instanceDio();
    return apiService;
  }

  void instanceDio(){
    _dio = Dio(BaseOptions(baseUrl: host,headers: header));

    _dio.interceptors.add(InterceptorsWrapper(
        onRequest: (options, handler){
          SecureStorage.of().get("token").then((token){
              header['token'] = token;
              options.headers = header;
              return handler.next(options);
          });
        },
      onError: (error, handler){
          print(error);
      }
    ));

    _dio.interceptors.add(InterceptorsWrapper(
        onResponse: (response, handler){
          final data = responseHandler(response, handler);
          if(StringUtils.isNotNull(data) && data['code'] == 'success'){
            response.data = data;
            return handler.next(response);
          }
        },
        onError: (response, handler){
          return handler.next(response);
        }
    ));
  }

  Future<dynamic> get(String url) async{
    return  await _dio.request(url, options: Options(method: 'get'));
  }

  Future<dynamic> post(String url, Object? body) async{
    return await _dio.request(url, data: body, options: Options(method: 'post'));
  }

  Future<dynamic> put(String url, Object? body) async{
    return await _dio.request(url, data: body, options: Options(method: 'put'));
  }

  Future<dynamic> delete(String url) async{
    return await _dio.request(url, options: Options(method: 'delete'));
  }

  dynamic responseHandler(var response, handler){
    BrnLoadingDialog.dismiss(context!);
    if(response.statusCode == 200){
      dynamic result = response.data;
      if(result["code"] == 'error'){
        BrnToast.show(result["message"], context!,
            gravity: BrnToastGravity.center,
            preIcon: const Image(image: AssetImage("assets/image/error.png"), width: 20, height: 20)
        );
        return null;
      }else if(result['code'] == 'authority'){
          SecureStorage.of().remove("token");
          WebSocketInheritedWidget.of(context!)?.socket.disconnect();
          Navigator.pushNamed(context!, "/");
      }else if(result['code'] == 'renewal'){
          SecureStorage.of().set("token", result["data"]);
          _dio.fetch(response.requestOptions).then((r) => handler.resolve(r));
        return;
      }
      return result;
    }
    throw Exception('Failed to fetch data');
  }

}




